/*******************************************************************************
 * Copyright (c) 2009-2011 ETCORE Labs. All rights reserved. 
 * 
 * This software is the confidential and proprietary information of ETCORE Labs.
 * You shall not disclose such confidential information and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with ETCORE Labs. 
 * 
 * Support can be obtained from support forums at:  http://www.etcore.com/
 * /
 *******************************************************************************/
package etcore.webapp.grouptalk.admin.action;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import etcore.webapp.grouptalk.common.action.AbstractAction;
import etcore.webapp.grouptalk.common.config.Config;
import etcore.webapp.grouptalk.common.config.MessageNamespaces;
import etcore.webapp.grouptalk.common.config.Messages;
import etcore.webapp.grouptalk.common.config.PageConstants;
import etcore.webapp.grouptalk.common.object.Comment;
import etcore.webapp.grouptalk.common.object.Group;
import etcore.webapp.grouptalk.common.object.Message;
import etcore.webapp.grouptalk.common.object.MessageTags;
import etcore.webapp.grouptalk.common.object.Tag;
import etcore.webapp.grouptalk.common.object.TagContainer;
import etcore.webapp.grouptalk.common.object.Topic;
import etcore.webapp.grouptalk.common.service.GroupService;
import etcore.webapp.grouptalk.common.service.MessageService;
import etcore.webapp.grouptalk.common.service.MessageTagsService;
import etcore.webapp.grouptalk.common.service.TagContainerService;
import etcore.webapp.grouptalk.common.service.TagService;
import etcore.webapp.grouptalk.common.service.TopicService;
import etcore.webapp.grouptalk.user.object.User;
import etcore.webapp.grouptalk.user.service.MemberService;
import etcore.webapp.grouptalk.user.service.UserService;
import etcore.webapp.grouptalk.util.DateUtil;
import etcore.webapp.grouptalk.util.SearchUtil;
import etcore.webapp.grouptalk.util.StringDisplay;
import etcore.webapp.grouptalk.util.Symbols;

/**
 * This action validates the request and executes the command of showing the
 * group detail administration page,then set the corresponding attributes for
 * output
 * 
 * @author ETCORE GroupTalk Developers
 * 
 */
public class GroupDetailAction extends AbstractAction {

	private static final long serialVersionUID = 7635783106939934395L;
	// validate result
	public static final int ACCESS_ALLOWED = 0;
	public static final int ERROR = 1;
	public static final int NOT_LOGGED = 2;

	// parameter/attributes constants

	public static final String CMD_VALUE = "addGmessage";

	// utility constants

	public static final String MINUS_ONE = "-1";

	public static final String VIEWER = "viewer";
	public static final String REDUCE = "reduceAllocation";
	public static final String ADD = "addAllocation";

	public static final String INPUT_DATE = "inputDate";
	public static final String COUNT = "count";
	public static final String SIZE = "size";
	public static final String COMMENT_NUM = "commentNum";
	public static final String LAST_COMMENT = "lastComment";

	@Override
	public int validate(HttpServletRequest request, HttpServletResponse response) {

		boolean isAdmin = (Boolean) request.getAttribute(PageConstants.ISADMIN);
		boolean notLogged = (Boolean) request
				.getAttribute(PageConstants.NOTLOGGED);
		if (notLogged)
			return NOT_LOGGED;
		GroupService groupService = new GroupService();
		String gid = request.getParameter(PageConstants.ID);
		Group group = null;
		if (gid != null) {
			group = groupService.findById(new Integer(gid));
		}
		if (group != null && isAdmin) {
			request.setAttribute(PageConstants.GROUP, group);
			if (group.getOpen() == 3)
				request.setAttribute(VIEWER,
						PageConstants.PAGE_NAME_BOOKMARKSADMIN);
			else
				request.setAttribute(VIEWER,
						PageConstants.PAGE_NAME_GROUPDETAIL);

			return ACCESS_ALLOWED;
		}

		return ERROR;

	}

	@Override
	public String getForward(HttpServletRequest request, int validationResult) {
		if (NOT_LOGGED == validationResult) {
			request.setAttribute("init", "login");
			return "/";
		}
		if (ERROR == validationResult)
			return PageConstants.ACTION_PATH_ERROR;
		return PageConstants.PAGE_PATH_GROUPDETAIL;
	}

	@Override
	public String getRedirect(HttpServletRequest request, int validationResult) {
		// TODO Auto-generated method stub

		return null;
	}

	@Override
	public void execute(int validationResult, HttpServletRequest request,
			HttpServletResponse response) {
		if (ACCESS_ALLOWED == validationResult) {
			String tid = request.getParameter(PageConstants.TID);
			processIndex(request);
			getTagContainers(request);
			addGmessage(request);
			mergeOrDeleteMessage(request);
			getGroups(request);
			getTopics(request);

			getTemplate(request);
			if (tid != null)
				getMessages(request);

		}
		// TODO Auto-generated method stub

	}

	private void processIndex(HttpServletRequest request) {
		String gid = request.getParameter(PageConstants.ID);
		String op = request.getParameter("op");
		if ("index".equals(op)) {
			SearchUtil.updateIndex(new Integer(gid));

		}

	}
	
	private void addGmessage(HttpServletRequest request) {
		String cmd = request.getParameter(PageConstants.CMD);
		if (CMD_VALUE.equals(cmd)) {
			try {

				HttpSession session = request.getSession(true);
				User user = (User) session
						.getAttribute(PageConstants.SESSIONUSER);
				String name = request.getParameter(PageConstants.NAME);

				String tag = request.getParameter(PageConstants.TAG);
				String flag = request.getParameter(PageConstants.FLAG);
				String source = request.getParameter(PageConstants.SOURCE);
				String stime = request.getParameter(PageConstants.STIME);
				String tid = request.getParameter(PageConstants.TID);
				String content = request.getParameter(PageConstants.CONTENT);
				if (tid != null && !tid.equals(MINUS_ONE) && user != null
						&& name != null) {

					Message message = new Message();
					MessageService messageService = new MessageService();

					message.setName(name);

					message.setTid(new Integer(tid));
					message.setFlag(new Integer(0));
					if (content != null) {

						message.setContent(content);

					}
					if (flag != null)
						message.setFlag(Integer.parseInt(flag));
					message.setTag(tag);
					if (source != null)
						message.setSource(source);
					message.setStime(stime);
					message.setUp(new Integer(0));
					message.setAddtime(DateUtil.getTime(Config.getProperty(Config.HOURS_DIFFERENCE)));
					message.setNum(new Integer(0));
					message.setUserName(user.getUserName());
					messageService.save(message);

					@SuppressWarnings("unchecked")
					List<TagContainer> tagContainers = (List<TagContainer>) request
							.getAttribute(PageConstants.TAGCONTAINERS);
					if (tagContainers != null && tagContainers.size() > 0) {
						MessageTagsService messageTagsService = new MessageTagsService();

						for (TagContainer tagContainer : tagContainers) {
							String param = PageConstants.TAGCONTAINERID
									+ tagContainer.getId();
							String[] tagIds = request.getParameterValues(param);
							if (tagIds != null && tagIds.length > 0) {
								for (String tagId : tagIds) {
									if (tagId != null
											&& !Symbols.BLANK.equals(tagId)
											&& !MINUS_ONE.equals(tagId)) {
										MessageTags messageTags = new MessageTags();
										messageTags
												.setTagid(new Integer(tagId));
										messageTags.setMid(message.getId());
										messageTagsService.save(messageTags);
									}
								}
							}
						}
					}
					String msg = null;
					String lang = (String) session.getAttribute(Messages.LANG);
					if (lang != null && lang.equals(Messages.LANG_EN)) {
						msg = Messages.getELabel(Messages.MSG_SUCCESS);
					} else {
						msg = Messages.getLabel(Messages.MSG_SUCCESS);
					}
					request.setAttribute(PageConstants.MSG, msg);
				}

			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private void mergeOrDeleteMessage(HttpServletRequest request) {
		MessageService messageService = new MessageService();
		String gid = request.getParameter(PageConstants.ID);
		String gmid = request.getParameter(PageConstants.GMID);
		String up = request.getParameter(PageConstants.UP);
		String flag = request.getParameter("flag");
		String del = request.getParameter("del");
		request.setAttribute(SIZE,
				messageService.findSizeByGid(new Integer(gid)));
		if (del != null && del.equals("1")) {
			Message targetMessage = messageService.findById(new Integer(gmid));
			if (targetMessage != null)
				messageService.deleteSingle(targetMessage);
		}

		else if (gmid != null) {
			Message targetMessage = messageService.findById(new Integer(gmid));

			if (up != null && (up.equals("1") || up.equals("0"))) {
				targetMessage.setUp(new Integer(up));
				messageService.merge(targetMessage);
				up = null;
			}

			if (flag != null
					&& (flag.equals("1") || flag.equals("0")
							|| flag.equals("-1") || flag.equals("100"))) {

				if (targetMessage.getFlag() == -1 && "0".equals(flag))
					targetMessage.setAddtime(DateUtil.getTime(Config.getProperty(Config.HOURS_DIFFERENCE)));
				targetMessage.setFlag(new Integer(flag));
				targetMessage.setUp(new Integer(0));
				messageService.merge(targetMessage);
				flag = null;
			}

		}
	}

	private void getGroups(HttpServletRequest request) {
		List<Group> groupList = null;
		int groupNum = 50;
		String groupNumStr = request.getParameter(PageConstants.GROUPNUM);
		if (groupNumStr != null && !Symbols.BLANK.equals(groupNumStr))
			groupNum = Integer.parseInt(groupNumStr);
		GroupService groupService = new GroupService();
		Group group = (Group) request.getAttribute(PageConstants.GROUP);

		HttpSession session = request.getSession(true);
		String lang = (String) session.getAttribute(Messages.LANG);
		if (Messages.LANG_EN.equals(lang)) {
			if (group.getOpen() == 1 || group.getOpen() == 2)
				groupList = groupService.findBy3Properties(PageConstants.OPEN,
						group.getOpen(), Messages.LANG_EN, new Integer(1),
						PageConstants.NAV, group.getNav(), 0, groupNum);
			else
				groupList = groupService.findBy2Properties(PageConstants.OPEN,
						group.getOpen(), Messages.LANG_EN, new Integer(1), 0,
						groupNum);
		} else {
			if (group.getOpen() == 1 || group.getOpen() == 2)
				groupList = groupService.findBy3Properties(PageConstants.OPEN,
						group.getOpen(), Messages.LANG_LOCAL, new Integer(1),
						PageConstants.NAV, group.getNav(), 0, groupNum);
			else
				groupList = groupService.findBy2Properties(PageConstants.OPEN,
						group.getOpen(), Messages.LANG_LOCAL, new Integer(1),
						0, groupNum);

		}
		request.setAttribute(PageConstants.GROUPS, groupList);
	}

	private void getTagContainers(HttpServletRequest request) {
		TagContainerService tagContainerService = new TagContainerService();

		String gid = request.getParameter(PageConstants.ID);
		List<TagContainer> tagContainers = tagContainerService.findByProperty(
				PageConstants.GID, new Integer(gid));
		if (tagContainers != null) {
			request.setAttribute(PageConstants.TAGCONTAINERS, tagContainers);
			request.setAttribute(PageConstants.TAGCONTAINERCOUNT,
					tagContainers.size());
			TagService tagService = new TagService();
			for (TagContainer tagContainer : tagContainers) {

				List<Tag> tags = tagService.findByProperty(
						PageConstants.TAGCONTAINERID, tagContainer.getId());
				if (tags != null) {
					request.setAttribute(tagContainer.getId()
							+ PageConstants.TAGS, tags);
					request.setAttribute(tagContainer.getId()
							+ PageConstants.TAGCOUNT, tags.size());
				}
			}

		}
	}

	private void getTopics(HttpServletRequest request) {
		TopicService topicService = new TopicService();
		Group group = (Group) request.getAttribute(PageConstants.GROUP);
		String id = request.getParameter(PageConstants.ID);
		String tid = request.getParameter(PageConstants.TID);
		List<Topic> topics = topicService.findByProperty(PageConstants.GID,
				new Integer(id));
		request.setAttribute(PageConstants.TOPICS, topics);
		MessageService messageService = new MessageService();
		for (Topic topic : topics) {
			request.setAttribute(topic.getId() + SIZE, messageService
					.findAllSizeByProperty(PageConstants.TID, topic.getId()));
			if (tid == null) {
				long hidden = 0, todayAdded = 0;
				@SuppressWarnings("rawtypes")
				List msgs = messageService.findAllByProperty(PageConstants.TID,
						topic.getId(), 0, 5);
				request.setAttribute(topic.getId() + PageConstants.MSGS, msgs);

				hidden = messageService.findSizeByPropertyAndFlag(
						PageConstants.TID, topic.getId(), -1);
				todayAdded = messageService.findSizeByFutureDaysAndTid(0,
						topic.getId());
				request.setAttribute(topic.getId() + "hidden", hidden);
				request.setAttribute(topic.getId() + "todayAdded", todayAdded);
				for (int k = 0; k < msgs.size(); k++) {
					Object[] tempm = (Object[]) msgs.get(k);
					Integer tempm_id = (Integer) tempm[0];
					String tempm_source = (String) tempm[9];
					String tempm_stime = (String) tempm[10];
					Long commentNum = messageService.findCommentNum(tempm_id);
					Comment tmpG = messageService.findLastComment(tempm_id);
					request.setAttribute(tempm_id + COMMENT_NUM, commentNum);
					if (tmpG != null)
						request.setAttribute(tempm_id + LAST_COMMENT,
								tmpG.getTime());

					if (group.getOpen() == 4) {
						StringBuffer reminderDate = StringDisplay
								.getReminderDateStringBuffer(tempm_source,
										tempm_stime);
						request.setAttribute(tempm_id + "reminderDate",
								reminderDate.toString());
					}
				}
			}

		}

	}

	@SuppressWarnings("rawtypes")
	private void allocate(HttpServletRequest request) {
		String cmd = request.getParameter(PageConstants.CMD);

		if (!(ADD.equals(cmd) || REDUCE.equals(cmd)))
			return;
		HttpSession session = request.getSession(true);
		String startDate = request.getParameter(PageConstants.START_DATE);
		String endDate = request.getParameter(PageConstants.END_DATE);
		String countStr = request.getParameter(COUNT);
		String tid = request.getParameter(PageConstants.TID);
		MessageService messageService = new MessageService();

		if(countStr==null||Symbols.BLANK.equals(countStr)) return;
		int dateError = 0;
		if (startDate == null || Symbols.BLANK.equals(startDate.trim())) {
			dateError = 1;
		}
		if (dateError == 0
				&& (endDate == null || Symbols.BLANK.equals(endDate.trim())))
			endDate = startDate;

		int gap = 0;
		if (dateError == 0)
			gap = DateUtil.getQuot(endDate, startDate);

		if (dateError == 1 || gap < 0) {
			String msg = null;
			String lang = (String) session.getAttribute(Messages.LANG);
			if (lang != null && lang.equals(Messages.LANG_EN)) {
				msg = Messages.getELabel(Messages.MSG_DATE_ERROR);
			} else {
				msg = Messages.getLabel(Messages.MSG_DATE_ERROR);
			}
			request.setAttribute(PageConstants.MSG, msg);

			return;

		}
		int count = Integer.parseInt(countStr);
		UserService userService=new UserService();
		if (ADD.equals(cmd)) {
			int MAX = 200;
			long hidden = messageService.findSizeByPropertyAndFlag(
					PageConstants.TID, new Integer(tid), -1);
			if (count * gap > hidden) {
				String msg = null;
				String lang = (String) session.getAttribute(Messages.LANG);
				if (lang != null && lang.equals(Messages.LANG_EN)) {
					msg = Messages.getELabel(Messages.MSG_ALLOCATION_LACKNESS);
				} else {
					msg = Messages.getLabel(Messages.MSG_ALLOCATION_LACKNESS);
				}
				request.setAttribute(PageConstants.MSG, msg);

				return;
			}
			MemberService memberService = new MemberService();
			long adminCount = memberService.getSysAdminNum();
			int targetCount = count * (gap+1) > MAX ? MAX : count * (gap+1);
			if (targetCount > adminCount)
				targetCount = (int) adminCount;

			int targetStartMax = (int) (adminCount - targetCount);
			int targetStart = (int) (Math.random() *targetStartMax);
			String admins = memberService.getSystemAdmins(targetStart,
					targetCount);
			String[] adminArray = admins.split(Symbols.COMMA);
			int length = adminArray.length;
			int random = 0;
			int MAX_SECONDS=10*60*60,MIN_START_SECONDS=8*60*60,seconds=0;
			String addTime=null;
			for (int i = 0; i <= gap; i++) {
				String targetDate = DateUtil.getNextDate(startDate, i);
				List ids = messageService.findIDsByPropertyAndFlag(
						PageConstants.TID, new Integer(tid), -1, 0, count);
				for (Iterator iter = ids.iterator(); iter.hasNext();) {
					Integer id = (Integer) iter.next();
					Message message = messageService.findById(id);
					seconds=(int)(Math.random()*MAX_SECONDS)+MIN_START_SECONDS;
					addTime=DateUtil.getLaterTime(targetDate, seconds);
					message.setAddtime(addTime);

					message.setFlag(0);
					random = (int) (Math.random() *length);
					message.setUserName(adminArray[random]);
					messageService.merge(message);
					User user=userService.findByUserName(adminArray[random]);
					if(user!=null) {
						user.setLastTime(DateUtil.getTime(Config.getProperty(Config.HOURS_DIFFERENCE)));
						user.setLoginNum(user.getLoginNum()+3);
						userService.merge(user);
					}
					
				}

			}

		} else if (REDUCE.equals(cmd)) {

			long check = DateUtil.getQuot(startDate, DateUtil.getDate());
			if (check <= 0) {
				String msg = null;
				String lang = (String) session.getAttribute(Messages.LANG);
				if (lang != null && lang.equals(Messages.LANG_EN)) {
					msg = Messages.getELabel(Messages.REDUCE_OLD_ERROR);
				} else {
					msg = Messages.getLabel(Messages.REDUCE_OLD_ERROR);
				}
				request.setAttribute(PageConstants.MSG, msg);

				return;
			}
			for (int i = 0; i <= gap; i++) {
				String targetDate = DateUtil.getNextDate(startDate, i);
				List ids = messageService.findByFutureDaysAndTid(targetDate, 0,
						new Integer(tid), 0, count);
				for (Iterator iter = ids.iterator(); iter.hasNext();) {
					Integer id = (Integer) iter.next();
					Message message = messageService.findById(id);
					message.setFlag(-1);

					messageService.merge(message);
				}

			}
		}

	}

	private void getPostAnalysis(HttpServletRequest request) {
		int analysisUnit = 4;
		String tid = request.getParameter(PageConstants.TID);
		String inputDate = request.getParameter(INPUT_DATE);

		MessageService messageService = new MessageService();

		if (inputDate == null || Symbols.BLANK.equals(inputDate.trim())) {
			for (int i = 1; i <= analysisUnit; i++) {
				long previous = messageService.findSizeByFutureDaysAndTid(i,
						new Integer(tid));
				request.setAttribute("date" + i, DateUtil.getPreviousDate(i));
				request.setAttribute("added" + i, previous);
			}
			String currentDate = DateUtil.getDate();
			request.setAttribute("currentDate", currentDate);
			request.setAttribute("currentAdded", messageService
					.findSizeByFutureDaysAndTid(currentDate, 0,
							new Integer(tid)));
			for (int i = -1; i >= -analysisUnit; i--) {
				long future = messageService.findSizeByFutureDaysAndTid(i,
						new Integer(tid));
				request.setAttribute("added" + i, future);
				request.setAttribute("date" + i, DateUtil.getNextDate(-i));
			}
		} else {
			for (int i = 1; i <= analysisUnit; i++) {
				long previous = messageService.findSizeByFutureDaysAndTid(
						inputDate, i, new Integer(tid));
				request.setAttribute("date" + i,
						DateUtil.getPreviousDate(inputDate, i));
				request.setAttribute("added" + i, previous);
			}
			request.setAttribute("currentDate", inputDate);
			request.setAttribute("currentAdded", messageService
					.findSizeByFutureDaysAndTid(inputDate, 0, new Integer(tid)));
			for (int i = -1; i >= -analysisUnit; i--) {
				long future = messageService.findSizeByFutureDaysAndTid(
						inputDate, i, new Integer(tid));
				request.setAttribute("added" + i, future);
				request.setAttribute("date" + i,
						DateUtil.getNextDate(inputDate, -i));
			}
		}
		request.setAttribute("analysisUnit", analysisUnit);
	}

	private void getMessages(HttpServletRequest request) {
		allocate(request);
		int intpageid = 1;
		String tid = request.getParameter(PageConstants.TID);
		int unit = 20;
		long all = 0;
		int begin, pagenums;
		String pageid = request.getParameter("pageid");
		MessageService messageService = new MessageService();
		if (pageid != null)
			intpageid = Integer.parseInt(pageid);
		all = messageService.findAllSizeByProperty(PageConstants.TID,
				new Integer(tid));
		pagenums = (int) ((all + unit - 1) / unit);
		begin = unit * (intpageid - 1);
		long hidden = messageService.findSizeByPropertyAndFlag(
				PageConstants.TID, new Integer(tid), -1);
		long todayAdded = messageService.findSizeByFutureDaysAndTid(0,
				new Integer(tid));
		request.setAttribute("hidden", hidden);
		request.setAttribute("todayAdded", todayAdded);

		@SuppressWarnings("rawtypes")
		List messages = messageService.findAllByProperty(PageConstants.TID,
				new Integer(tid), begin, unit);
		Group group = (Group) request.getAttribute(PageConstants.GROUP);
		for (int k = 0; k < messages.size(); k++) {
			Object[] tempm = (Object[]) messages.get(k);
			Integer tempm_id = (Integer) tempm[0];
			String tempm_source = (String) tempm[9];
			String tempm_stime = (String) tempm[10];
			Long commentNum = messageService.findCommentNum(tempm_id);
			Comment tmpG = messageService.findLastComment(tempm_id);
			request.setAttribute(tempm_id + COMMENT_NUM, commentNum);
			if (tmpG != null)
				request.setAttribute(tempm_id + LAST_COMMENT, tmpG.getTime());

			if (group.getOpen() == 4) {
				StringBuffer reminderDate = StringDisplay
						.getReminderDateStringBuffer(tempm_source, tempm_stime);
				request.setAttribute(tempm_id + "reminderDate",
						reminderDate.toString());
			}
		}

		request.setAttribute(PageConstants.MSGS, messages);
		request.setAttribute(PageConstants.PAGENUMS, pagenums);
		request.setAttribute(PageConstants.ALL, all);
		request.setAttribute(PageConstants.UNIT, unit);
		request.setAttribute(PageConstants.INTPAGEID, intpageid);
		getPostAnalysis(request);
	}

	private void getTemplate(HttpServletRequest request) {
		String template = request.getParameter(PageConstants.TEMPLATE);
		String tid = request.getParameter(PageConstants.TID);
		if (Messages.TRUE.equals(template) && tid != null) {
			Message templateMsg = null;
			MessageService messageService = new MessageService();
			@SuppressWarnings("rawtypes")
			List templates = messageService.findTemplates(PageConstants.TID,
					new Integer(tid), 0, 1);
			if (templates != null && templates.size() > 0)
				templateMsg = (Message) templates.get(0);
			request.setAttribute(PageConstants.TEMPLATE, templateMsg);
		}

	}

	@Override
	public boolean isForward(int validationResult) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean enablePostLoad() {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see etcore.webapp.grouptalk.controller.action.AbstractAction#
	 * buildSelfContextAndAttributes(int, javax.servlet.http.HttpServletRequest)
	 */
	@Override
	public List<String> getNamespacesOfMessages(HttpServletRequest request) {
		// TODO Auto-generated method stub
		List<String> namespaces = new ArrayList<String>();
		namespaces.add(MessageNamespaces.GROUP_ADMIN);
		return namespaces;
	}

}
